
                    <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
                        <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
                    </svg>
                    <p>为了增强<a href="https://so.csdn.net/so/search?q=%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86&amp;spm=1001.2101.3001.7020" target="_blank" class="hl hl-1" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.7020&quot;,&quot;dest&quot;:&quot;https://so.csdn.net/so/search?q=%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86&amp;spm=1001.2101.3001.7020&quot;,&quot;extra&quot;:&quot;{\&quot;searchword\&quot;:\&quot;状态管理\&quot;}&quot;}" data-tit="状态管理" data-pretit="状态管理">状态管理</a>框架对类对象中属性的观测能力，开发者可以使用@ObservedV2装饰器和@Trace装饰器装饰类以及类中的属性。</p> 
<blockquote> 
 <p><strong>说明：</strong></p> 
 <p>@ObservedV2与@Trace<a href="https://so.csdn.net/so/search?q=%E8%A3%85%E9%A5%B0%E5%99%A8&amp;spm=1001.2101.3001.7020" target="_blank" class="hl hl-1" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.7020&quot;,&quot;dest&quot;:&quot;https://so.csdn.net/so/search?q=%E8%A3%85%E9%A5%B0%E5%99%A8&amp;spm=1001.2101.3001.7020&quot;,&quot;extra&quot;:&quot;{\&quot;searchword\&quot;:\&quot;装饰器\&quot;}&quot;}" data-tit="装饰器" data-pretit="装饰器">装饰器</a>从API version 12开始支持。</p> 
 <p>当前状态管理（V2试用版）仍在逐步开发中，相关功能尚未成熟，建议开发者尝鲜试用。</p> 
</blockquote> 
<h3><a name="t0"></a><a id="_8"></a>概述</h3> 
<p>@ObservedV2装饰器与@Trace装饰器用于装饰类以及类中的属性，使得被装饰的类和属性具有深度观测的能力：</p> 
<ul><li>@ObservedV2装饰器与@Trace装饰器需要配合使用，单独使用@ObservedV2装饰器或@Trace装饰器没有任何作用。</li><li>被@Trace装饰器装饰的属性property变化时，仅会通知property关联的组件进行刷新。</li><li>在嵌套类中，嵌套类中的属性property被@Trace装饰且嵌套类被@ObservedV2装饰时，才具有触发UI刷新的能力。</li><li>在继承类中，父类或子类中的属性property被@Trace装饰且该property所在类被@ObservedV2装饰时，才具有触发UI刷新的能力。</li><li>未被@Trace装饰的属性用在UI中无法感知到变化，也无法触发UI刷新。</li><li>@ObservedV2的类实例目前不支持使用JSON.stringify进行序列化。</li></ul> 
<h3><a name="t1"></a><a id="V1_19"></a>状态管理V1版本对嵌套<a href="https://so.csdn.net/so/search?q=%E7%B1%BB%E5%AF%B9%E8%B1%A1&amp;spm=1001.2101.3001.7020" target="_blank" class="hl hl-1" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.7020&quot;,&quot;dest&quot;:&quot;https://so.csdn.net/so/search?q=%E7%B1%BB%E5%AF%B9%E8%B1%A1&amp;spm=1001.2101.3001.7020&quot;,&quot;extra&quot;:&quot;{\&quot;searchword\&quot;:\&quot;类对象\&quot;}&quot;}" data-tit="类对象" data-pretit="类对象">类对象</a>属性变化直接观测的局限性</h3> 
<p>现有状态管理V1版本无法实现对嵌套类对象属性变化的直接观测。</p> 
<pre data-index="0" class="prettyprint set-code-show" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">@Observed
class Father {
  son: Son;

  constructor(name: string, age: number) {
    this.son = new Son(name, age);
  }
}
@Observed
class Son {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}
@Entry
@Component
struct Index {
  @State father: Father = new Father("John", 8);

  build() {
    Row() {
      Column() {
        Text(`name: ${this.father.son.name} age: ${this.father.son.age}`)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() =&gt; {
            this.father.son.age++;
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:0,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<p>上述代码中，点击Text<span class="edu-hl hl hl-1" data-report-view="{&quot;spm&quot;:&quot;1001.2101.3001.7020&quot;,&quot;extra&quot;:&quot;{\&quot;word\&quot;:\&quot;组件\&quot;}&quot;}" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.7020&quot;,&quot;extra&quot;:&quot;{\&quot;word\&quot;:\&quot;组件\&quot;}&quot;}" data-tit="组件" data-pretit="组件">组件</span>增加age的值时，不会触发UI刷新。因为在现有的状态管理框架下，无法观测到嵌套类中属性age的值变化。V1版本的解决方案是使用[@ObjectLink装饰器]与自定义组件的方式实现观测。</p> 
<pre data-index="1" class="prettyprint set-code-show" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">@Observed
class Father {
  son: Son;

  constructor(name: string, age: number) {
    this.son = new Son(name, age);
  }
}
@Observed
class Son {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}
@Component
struct Child {
  @ObjectLink son: Son;

  build() {
    Row() {
      Column() {
        Text(`name: ${this.son.name} age: ${this.son.age}`)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() =&gt; {
            this.son.age++;
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}
@Entry
@Component
struct Index {
  @State father: Father = new Father("John", 8);

  build() {
    Column() {
      Child({son: this.father.son})
    }
  }
}
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:1,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<p>通过这种方式虽然能够实现对嵌套类中属性变化的观测，但是当嵌套层级较深时，代码将会变得十分复杂，易用性差。因此推出类装饰器@ObservedV2与成员变量装饰器@Trace，增强对嵌套类中属性变化的观测能力。</p> 
<h3><a name="t2"></a><a id="_119"></a>装饰器说明</h3> 
<div class="table-box"><table><thead><tr><th>@ObservedV2类装饰器</th><th>说明</th></tr></thead><tbody><tr><td>装饰器参数</td><td>无</td></tr><tr><td>类装饰器</td><td>装饰class。需要放在class的定义前，使用new创建类对象。</td></tr></tbody></table></div> 
<div class="table-box"><table><thead><tr><th>@Trace成员变量装饰器</th><th>说明</th></tr></thead><tbody><tr><td>装饰器参数</td><td>无</td></tr><tr><td>可装饰的变量</td><td>class中成员属性。属性的类型可以为number、string、boolean、class、Array、Date、Map、Set等类型。</td></tr></tbody></table></div> 
<h3><a name="t3"></a><a id="_131"></a>观察变化</h3> 
<p>使用@ObservedV2装饰的类中被@Trace装饰的属性具有被观测变化的能力，当该属性值变化时，会触发该属性绑定的UI组件刷新。</p> 
<ul><li>在嵌套类中使用@Trace装饰的属性具有被观测变化的能力。</li></ul> 
<pre data-index="2" class="prettyprint set-code-show" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">@ObservedV2
class Son {
  @Trace age: number = 100;
}
class Father {
  son: Son = new Son();
}
@Entry
@ComponentV2
struct Index {
  father: Father = new Father();

  build() {
    Column() {
      // 当点击改变age时，Text组件会刷新
      Text(`${this.father.son.age}`)
        .onClick(() =&gt; {
          this.father.son.age++;
      })
    }
  }
}

<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:2,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<ul><li>在继承类中使用@Trace装饰的属性具有被观测变化的能力。</li></ul> 
<pre data-index="3" class="prettyprint set-code-show" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">@ObservedV2
class Father {
  @Trace name: string = "Tom";
}
class Son extends Father {
}
@Entry
@ComponentV2
struct Index {
  son: Son = new Son();

  build() {
    Column() {
      // 当点击改变name时，Text组件会刷新
      Text(`${this.son.name}`)
        .onClick(() =&gt; {
          this.son.name = "Jack";
      })
    }
  }
}
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:3,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<ul><li>类中使用@Trace装饰的静态属性具有被观测变化的能力。</li></ul> 
<pre data-index="4" class="prettyprint set-code-show" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">@ObservedV2
class Manager {
  @Trace static count: number = 1;
}
@Entry
@ComponentV2
struct Index {
  build() {
    Column() {
      // 当点击改变count时，Text组件会刷新
      Text(`${Manager.count}`)
        .onClick(() =&gt; {
          Manager.count++;
      })
    }
  }
}
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:4,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<ul><li> <p>@Trace装饰内置类型时，可以观测各自API导致的变化：</p> 
  <div class="table-box"><table><thead><tr><th>类型</th><th>可观测变化的API</th></tr></thead><tbody><tr><td>Array</td><td>push、pop、shift、unshift、splice、copyWithin、fill、reverse、sort</td></tr><tr><td>Date</td><td>setFullYear, setMonth, setDate, setHours, setMinutes, setSeconds, setMilliseconds, setTime, setUTCFullYear, setUTCMonth, setUTCDate, setUTCHours, setUTCMinutes, setUTCSeconds, setUTCMilliseconds</td></tr><tr><td>Map</td><td>set, clear, delete</td></tr><tr><td>Set</td><td>add, clear, delete</td></tr></tbody></table></div></li></ul> 
<h3><a name="t4"></a><a id="_220"></a>使用限制</h3> 
<p>@ObservedV2与@Trace装饰器存在以下使用限制：</p> 
<ul><li>非@Trace装饰的成员属性用在UI上无法触发UI刷新。</li></ul> 
<pre data-index="5" class="prettyprint set-code-show" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">@ObservedV2
class Person {
  id: number = 0;
  @Trace age: number = 8;
}
@Entry
@ComponentV2
struct Index {
  person: Person = new Person();

  build() {
    Column() {
      // age被@Trace装饰，用在UI中可以触发UI刷新
      Text(`${this.person.age}`)
      // id未被@Trace装饰，用在UI中不会触发UI刷新
      Text(`${this.person.id}`) // 当id变化时不会刷新
    }
  }
}
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:5,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<ul><li>@Trace不能用在没有被@ObservedV2装饰的class上。</li></ul> 
<pre data-index="6" class="set-code-show prettyprint" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">class User {
  id: number = 0;
  @Trace name: string = "Tom"; // 错误用法，编译时报错
}
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:6,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<ul><li>@Trace是class中属性的装饰器，不能用在struct中。</li></ul> 
<pre data-index="7" class="set-code-show prettyprint" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">@ComponentV2
struct Comp {
  @Trace message: string = "Hello World"; // 错误用法，编译时报错

  build() {
  }
}
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:7,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<ul><li>@ObservedV2、@Trace不能与[@Observed]、[@Track]混合使用。</li></ul> 
<pre data-index="8" class="set-code-show prettyprint" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">@Observed
class User {
  @Trace name: string = "Tom"; // 错误用法，编译时报错
}

@ObservedV2
class Person {
  @Track name: string = "Jack"; // 错误用法，编译时报错
}
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:8,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<ul><li>使用@ObservedV2与@Trace装饰的类不能和[@State]等V1的装饰器混合使用，编译时报错。</li></ul> 
<pre data-index="9" class="prettyprint set-code-show" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">// 以@State装饰器为例
@ObservedV2
class Job {
  @Trace jobName: string = "Teacher";
}
@ObservedV2
class Info {
  @Trace name: string = "Tom";
  @Trace age: number = 25;
  job: Job = new Job();
}
@Entry
@Component
struct Index {
  @State info: Info = new Info(); // 无法混用，编译时报错

  build() {
    Column() {
      Text(`name: ${this.info.name}`)
      Text(`age: ${this.info.age}`)
      Text(`jobName: ${this.info.job.jobName}`)
      Button("change age")
        .onClick(() =&gt; {
          this.info.age++;
      })
      Button("Change job")
        .onClick(() =&gt; {
          this.info.job.jobName = "Doctor";
      })
    }
  }
}
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:9,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<ul><li>继承自@ObservedV2的类无法和@State等V1的装饰器混用，运行时报错。</li></ul> 
<pre data-index="10" class="prettyprint set-code-show" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">// 以@State装饰器为例
@ObservedV2
class Job {
  @Trace jobName: string = "Teacher";
}
@ObservedV2
class Info {
  @Trace name: string = "Tom";
  @Trace age: number = 25;
  job: Job = new Job();
}
class Message extends Info {
    constructor() {
        super();
    }
}
@Entry
@Component
struct Index {
  @State message: Message = new Message(); // 无法混用，运行时报错

  build() {
    Column() {
      Text(`name: ${this.message.name}`)
      Text(`age: ${this.message.age}`)
      Text(`jobName: ${this.message.job.jobName}`)
      Button("change age")
        .onClick(() =&gt; {
          this.message.age++;
      })
      Button("Change job")
        .onClick(() =&gt; {
          this.message.job.jobName = "Doctor";
      })
    }
  }
}
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:10,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<ul><li>@ObservedV2的类实例目前不支持使用JSON.stringify进行序列化。</li></ul> 
<h3><a name="t5"></a><a id="_364"></a>使用场景</h3> 
<h4><a name="t6"></a><a id="_366"></a>嵌套类场景</h4> 
<p>在下面的嵌套类场景中，Pencil类是Son类中最里层的类，Pencil类被@ObservedV2装饰且属性length被@Trace装饰，此时length的变化能够被观测到。</p> 
<p>@Trace装饰器与现有状态管理框架的[@Track]与[@State]装饰器的能力不同，@Track使class具有属性级更新的能力，但并不具备深度观测的能力；而@State只能观测到对象本身以及第一层的变化，对于多层嵌套场景只能通过封装自定义组件，搭配[@Observed]和[@ObjectLink]来实现观测。</p> 
<ul><li>点击Button(“change length”)，length是被@Trace装饰的属性，它的变化可以触发关联的UI组件，即UINode (1)的刷新，并输出"isRender id: 1"的日志。</li><li>自定义组件Page中的son是常规变量，因此点击Button(“assign Son”)并不会观测到变化。</li><li>当点击Button(“assign Son”)后，再点击Button(“change length”)并不会引起UI刷新。因为此时son的地址改变，其关联的UI组件并没有关联到最新的son。</li></ul> 
<pre data-index="11" class="prettyprint set-code-show" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">@ObservedV2
class Pencil {
  @Trace length: number = 21; // 当length变化时，会刷新关联的组件
}
class Bag {
  width: number = 50;
  height: number = 60;
  pencil: Pencil = new Pencil();
}
class Son {
  age: number = 5;
  school: string = "some";
  bag: Bag = new Bag();
}

@Entry
@ComponentV2
struct Page {
  son: Son = new Son();
  renderTimes: number = 0;
  isRender(id: number): number {
    console.info(`id: ${id} renderTimes: ${this.renderTimes}`);
    this.renderTimes++;
    return 40;
  }

  build() {
    Column() {
      Text('pencil length'+ this.son.bag.pencil.length)
        .fontSize(this.isRender(1))   // UINode (1)
      Button("change length")
        .onClick(() =&gt; {
          // 点击更改length值，UINode（1）会刷新
          this.son.bag.pencil.length += 100;
        })
      Button("assign Son")
        .onClick(() =&gt; {
          // 由于变量son非状态变量，因此无法刷新UINode（1）
          this.son = new Son();
        })
    }
  }
}
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:11,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<h4><a name="t7"></a><a id="_422"></a>继承类场景</h4> 
<p>@Trace支持在类的继承场景中使用，无论是在基类还是继承类中，只有被@Trace装饰的属性才具有被观测变化的能力。 以下例子中，声明class GrandFather、Father、Uncle、Son、Cousin，继承关系如下图。</p> 
<p><img src="https://i-blog.csdnimg.cn/direct/20bdea5a77834eb5bf3d2aed6db35800.png" alt="外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传"></p> 
<p>创建类Son和类Cousin的实例，点击Button(‘change Son age’)和Button(‘change Cousin age’)可以触发UI的刷新。</p> 
<pre data-index="12" class="prettyprint set-code-show" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">@ObservedV2
class GrandFather {
  @Trace age: number = 0;

  constructor(age: number) {
    this.age = age;
  }
}
class Father extends GrandFather{
  constructor(father: number) {
    super(father);
  }
}
class Uncle extends GrandFather {
  constructor(uncle: number) {
    super(uncle);
  }
}
class Son extends Father {
  constructor(son: number) {
    super(son);
  }
}
class Cousin extends Uncle {
  constructor(cousin: number) {
    super(cousin);
  }
}
@Entry
@ComponentV2
struct Index {
  son: Son = new Son(0);
  cousin: Cousin = new Cousin(0);
  renderTimes: number = 0;

  isRender(id: number): number {
    console.info(`id: ${id} renderTimes: ${this.renderTimes}`);
    this.renderTimes++;
    return 40;
  }

  build() {
    Row() {
      Column() {
        Text(`Son ${this.son.age}`)
          .fontSize(this.isRender(1))
          .fontWeight(FontWeight.Bold)
        Text(`Cousin ${this.cousin.age}`)
          .fontSize(this.isRender(2))
          .fontWeight(FontWeight.Bold)
        Button('change Son age')
          .onClick(() =&gt; {
            this.son.age++;
          })
        Button('change Cousin age')
          .onClick(() =&gt; {
            this.cousin.age++;
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li><li style="color: rgb(153, 153, 153);">58</li><li style="color: rgb(153, 153, 153);">59</li><li style="color: rgb(153, 153, 153);">60</li><li style="color: rgb(153, 153, 153);">61</li><li style="color: rgb(153, 153, 153);">62</li><li style="color: rgb(153, 153, 153);">63</li><li style="color: rgb(153, 153, 153);">64</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:12,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<h4><a name="t8"></a><a id="Trace_498"></a>@Trace装饰基础类型的<span class="edu-hl hl hl-1" data-report-view="{&quot;spm&quot;:&quot;1001.2101.3001.7020&quot;,&quot;extra&quot;:&quot;{\&quot;word\&quot;:\&quot;数组\&quot;}&quot;}" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.7020&quot;,&quot;extra&quot;:&quot;{\&quot;word\&quot;:\&quot;数组\&quot;}&quot;}" data-tit="数组" data-pretit="数组">数组</span></h4> 
<p>@Trace装饰数组时，使用支持的API能够观测到变化。支持的API见[观察变化]。 在下面的示例中@ObservedV2装饰的Arr类中的属性numberArr是@Trace装饰的数组，当使用数组API操作numberArr时，可以观测到对应的变化。注意使用数组长度进行判断以防越界访问。</p> 
<pre data-index="13" class="prettyprint set-code-show" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">let nextId: number = 0;

@ObservedV2
class Arr {
  id: number = 0;
  @Trace numberArr: number[] = [];

  constructor() {
    this.id = nextId++;
    this.numberArr = [0, 1, 2];
  }
}

@Entry
@ComponentV2
struct Index {
  arr: Arr = new Arr();

  build() {
    Column() {
      Text(`length: ${this.arr.numberArr.length}`)
        .fontSize(40)
      Divider()
      if (this.arr.numberArr.length &gt;= 3) {
        Text(`${this.arr.numberArr[0]}`)
          .fontSize(40)
          .onClick(() =&gt; {
            this.arr.numberArr[0]++;
          })
        Text(`${this.arr.numberArr[1]}`)
          .fontSize(40)
          .onClick(() =&gt; {
            this.arr.numberArr[1]++;
          })
        Text(`${this.arr.numberArr[2]}`)
          .fontSize(40)
          .onClick(() =&gt; {
            this.arr.numberArr[2]++;
          })
      }

      Divider()

      ForEach(this.arr.numberArr, (item: number, index: number) =&gt; {
        Text(`${index} ${item}`)
          .fontSize(40)
      })

      Button('push')
        .onClick(() =&gt; {
          this.arr.numberArr.push(50);
        })

      Button('pop')
        .onClick(() =&gt; {
          this.arr.numberArr.pop();
        })

      Button('shift')
        .onClick(() =&gt; {
          this.arr.numberArr.shift();
        })

      Button('splice')
        .onClick(() =&gt; {
          this.arr.numberArr.splice(1, 0, 60);
        })


      Button('unshift')
        .onClick(() =&gt; {
          this.arr.numberArr.unshift(100);
        })

      Button('copywithin')
        .onClick(() =&gt; {
          this.arr.numberArr.copyWithin(0, 1, 2);
        })

      Button('fill')
        .onClick(() =&gt; {
          this.arr.numberArr.fill(0, 2, 4);
        })

      Button('reverse')
        .onClick(() =&gt; {
          this.arr.numberArr.reverse();
        })

      Button('sort')
        .onClick(() =&gt; {
          this.arr.numberArr.sort();
        })
    }
  }
}
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li><li style="color: rgb(153, 153, 153);">58</li><li style="color: rgb(153, 153, 153);">59</li><li style="color: rgb(153, 153, 153);">60</li><li style="color: rgb(153, 153, 153);">61</li><li style="color: rgb(153, 153, 153);">62</li><li style="color: rgb(153, 153, 153);">63</li><li style="color: rgb(153, 153, 153);">64</li><li style="color: rgb(153, 153, 153);">65</li><li style="color: rgb(153, 153, 153);">66</li><li style="color: rgb(153, 153, 153);">67</li><li style="color: rgb(153, 153, 153);">68</li><li style="color: rgb(153, 153, 153);">69</li><li style="color: rgb(153, 153, 153);">70</li><li style="color: rgb(153, 153, 153);">71</li><li style="color: rgb(153, 153, 153);">72</li><li style="color: rgb(153, 153, 153);">73</li><li style="color: rgb(153, 153, 153);">74</li><li style="color: rgb(153, 153, 153);">75</li><li style="color: rgb(153, 153, 153);">76</li><li style="color: rgb(153, 153, 153);">77</li><li style="color: rgb(153, 153, 153);">78</li><li style="color: rgb(153, 153, 153);">79</li><li style="color: rgb(153, 153, 153);">80</li><li style="color: rgb(153, 153, 153);">81</li><li style="color: rgb(153, 153, 153);">82</li><li style="color: rgb(153, 153, 153);">83</li><li style="color: rgb(153, 153, 153);">84</li><li style="color: rgb(153, 153, 153);">85</li><li style="color: rgb(153, 153, 153);">86</li><li style="color: rgb(153, 153, 153);">87</li><li style="color: rgb(153, 153, 153);">88</li><li style="color: rgb(153, 153, 153);">89</li><li style="color: rgb(153, 153, 153);">90</li><li style="color: rgb(153, 153, 153);">91</li><li style="color: rgb(153, 153, 153);">92</li><li style="color: rgb(153, 153, 153);">93</li><li style="color: rgb(153, 153, 153);">94</li><li style="color: rgb(153, 153, 153);">95</li><li style="color: rgb(153, 153, 153);">96</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:13,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<h4><a name="t9"></a><a id="Trace_601"></a>@Trace装饰对象数组</h4> 
<ul><li>@Trace装饰对象数组personList以及Person类中的age属性，因此当personList、age改变时均可以观测到变化。</li><li>点击Text组件更改age时，Text组件会刷新。</li></ul> 
<pre data-index="14" class="prettyprint set-code-show" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">let nextId: number = 0;

@ObservedV2
class Person {
  @Trace age: number = 0;

  constructor(age: number) {
    this.age = age;
  }
}

@ObservedV2
class Info {
  id: number = 0;
  @Trace personList: Person[] = [];

  constructor() {
    this.id = nextId++;
    this.personList = [new Person(0), new Person(1), new Person(2)];
  }
}

@Entry
@ComponentV2
struct Index {
  info: Info = new Info();

  build() {
    Column() {
      Text(`length: ${this.info.personList.length}`)
        .fontSize(40)
      Divider()
      if (this.info.personList.length &gt;= 3) {
        Text(`${this.info.personList[0].age}`)
          .fontSize(40)
          .onClick(() =&gt; {
            this.info.personList[0].age++;
          })

        Text(`${this.info.personList[1].age}`)
          .fontSize(40)
          .onClick(() =&gt; {
            this.info.personList[1].age++;
          })

        Text(`${this.info.personList[2].age}`)
          .fontSize(40)
          .onClick(() =&gt; {
            this.info.personList[2].age++;
          })
      }

      Divider()

      ForEach(this.info.personList, (item: Person, index: number) =&gt; {
        Text(`${index} ${item.age}`)
          .fontSize(40)
      })
    }
  }
}

<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li><li style="color: rgb(153, 153, 153);">58</li><li style="color: rgb(153, 153, 153);">59</li><li style="color: rgb(153, 153, 153);">60</li><li style="color: rgb(153, 153, 153);">61</li><li style="color: rgb(153, 153, 153);">62</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:14,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<h4><a name="t10"></a><a id="TraceMap_671"></a>@Trace装饰Map类型</h4> 
<ul><li>被@Trace装饰的Map类型属性可以观测到调用API带来的变化，包括 set、clear、delete。</li><li>因为Info类被@ObservedV2装饰且属性memberMap被@Trace装饰，点击Button(‘init map’)对memberMap赋值也可以观测到变化。</li></ul> 
<pre data-index="15" class="prettyprint set-code-show" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">@ObservedV2
class Info {
  @Trace memberMap: Map&lt;number, string&gt; = new Map([[0, "a"], [1, "b"], [3, "c"]]);
}

@Entry
@ComponentV2
struct MapSample {
  info: Info = new Info();

  build() {
    Row() {
      Column() {
        ForEach(Array.from(this.info.memberMap.entries()), (item: [number, string]) =&gt; {
          Text(`${item[0]}`)
            .fontSize(30)
          Text(`${item[1]}`)
            .fontSize(30)
          Divider()
        })
        Button('init map')
          .onClick(() =&gt; {
            this.info.memberMap = new Map([[0, "a"], [1, "b"], [3, "c"]]);
          })
        Button('set new one')
          .onClick(() =&gt; {
            this.info.memberMap.set(4, "d");
          })
        Button('clear')
          .onClick(() =&gt; {
            this.info.memberMap.clear();
          })
        Button('set the key: 0')
          .onClick(() =&gt; {
            this.info.memberMap.set(0, "aa");
          })
        Button('delete the first one')
          .onClick(() =&gt; {
            this.info.memberMap.delete(0);
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:15,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<h4><a name="t11"></a><a id="TraceSet_725"></a>@Trace装饰Set类型</h4> 
<ul><li>被@Trace装饰的Set类型属性可以观测到调用API带来的变化，包括 add, clear, delete。</li><li>因为Info类被@ObservedV2装饰且属性memberSet被@Trace装饰，点击Button(‘init set’)对memberSet赋值也可以观察变化。</li></ul> 
<pre data-index="16" class="prettyprint set-code-show" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">@ObservedV2
class Info {
  @Trace memberSet: Set&lt;number&gt; = new Set([0, 1, 2, 3, 4]);
}

@Entry
@ComponentV2
struct SetSample {
  info: Info = new Info();

  build() {
    Row() {
      Column() {
        ForEach(Array.from(this.info.memberSet.entries()), (item: [number, string]) =&gt; {
          Text(`${item[0]}`)
            .fontSize(30)
          Divider()
        })
        Button('init set')
          .onClick(() =&gt; {
            this.info.memberSet = new Set([0, 1, 2, 3, 4]);
          })
        Button('set new one')
          .onClick(() =&gt; {
            this.info.memberSet.add(5);
          })
        Button('clear')
          .onClick(() =&gt; {
            this.info.memberSet.clear();
          })
        Button('delete the first one')
          .onClick(() =&gt; {
            this.info.memberSet.delete(0);
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:16,&quot;runIdx&quot;:-1}}">代码解读</button></pre> 
<h4><a name="t12"></a><a id="TraceDate_773"></a>@Trace装饰Date类型</h4> 
<ul><li>@Trace装饰的Date类型属性可以观测调用API带来的变化，包括 setFullYear、setMonth、setDate、setHours、setMinutes、setSeconds、setMilliseconds、setTime、setUTCFullYear、setUTCMonth、setUTCDate、setUTCHours、setUTCMinutes、setUTCSeconds、setUTCMilliseconds。</li><li>因为Info类被@ObservedV2装饰且属性selectedDate被@Trace装饰，点击Button(‘set selectedDate to 2023-07-08’)对selectedDate赋值也可以观测到变化。</li></ul> 
<pre data-index="17" class="prettyprint set-code-show" style="user-select: auto;"><code class="has-numbering" onclick="mdcp.copyCode(event)" style="position: unset; user-select: auto;">@ObservedV2
class Info {
  @Trace selectedDate: Date = new Date('2021-08-08')
}

@Entry
@ComponentV2
struct DateSample {
  info: Info = new Info()

  build() {
    Column() {
      Button('set selectedDate to 2023-07-08')
        .margin(10)
        .onClick(() =&gt; {
          this.info.selectedDate = new Date('2023-07-08');
        })
      Button('increase the year by 1')
        .margin(10)
        .onClick(() =&gt; {
          this.info.selectedDate.setFullYear(this.info.selectedDate.getFullYear() + 1);
        })
      Button('increase the month by 1')
        .margin(10)
        .onClick(() =&gt; {
          this.info.selectedDate.setMonth(this.info.selectedDate.getMonth() + 1);
        })
      Button('increase the day by 1')
        .margin(10)
        .onClick(() =&gt; {
          this.info.selectedDate.setDate(this.info.selectedDate.getDate() + 1);
        })
      DatePicker({
        start: new Date('1970-1-1'),
        end: new Date('2100-1-1'),
        selected: this.info.selectedDate
      })
    }.width('100%')
  }
<div class="hljs-button {2} add_def" data-title="复制"></div></code><ul class="pre-numbering" style="opacity: 0.992152;"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li></ul><button class="btn-code-notes mdeditor" data-report-click="{&quot;spm&quot;:&quot;3001.10436&quot;,&quot;extra&quot;:{&quot;index&quot;:17,&quot;runIdx&quot;:-1}}">代码解读</button></pre>
                